package com.juneyao.log.logcenter.elasticsearch.impl;

import com.juneyao.log.logcenter.domain.request.LogOperateRequest;
import com.juneyao.log.logcenter.domain.response.LogOperateResponse;
import com.juneyao.log.logcenter.domain.vo.OperateResultData;
import com.juneyao.log.logcenter.elasticsearch.ElasticSearchOperateService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

/**
 * @author quanbiao
 * @date 2018-07-31
 */
@Service("elasticSearchOperateService")
public class ElasticSearchOperateServiceImpl implements ElasticSearchOperateService {

    private Logger logger = LoggerFactory.getLogger("ElasticSearchOperateServiceImpl");

    /**
     * es返回字段
     */
    private static final String[] showFields = {"request_time", "params", "service_name", "type",  "user_name", "ip"};

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 操作日志分页查询
     * @param request
     * @return
     */
    @Override
    public OperateResultData getOpResultData(LogOperateRequest request) {
        //返回结果
        OperateResultData resultData = new OperateResultData();

        //操作时间降序排列
        Sort opTimeDesc = Sort.by("request_time").descending();

        //构建es分页request，es的分页是从0开始的，索引使用页码减一
        PageRequest pageRequest = PageRequest.of(request.getPageNum() - 1, request.getPageSize(), opTimeDesc);

        //条件组合查询
        BoolQueryBuilder conditionQuery = QueryBuilders.boolQuery();
        //操作时间
        if(StringUtils.isNotBlank(request.getBeginDate()) && StringUtils.isNotBlank(request.getEndDate())){
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("request_time")
                    .gte(request.getBeginDate() + " 00:00:00.000")
                    .lte(request.getEndDate() + " 23:59:59.999");
            conditionQuery.filter(rangeQueryBuilder);
        }
        //服务名
        if(StringUtils.isNotBlank(request.getServiceName())){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("service_name", request.getServiceName());
            conditionQuery.filter(termQueryBuilder);
        }
        //系统类型
        if(StringUtils.isNotBlank(request.getSystemType())){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("system_type", request.getSystemType());
            conditionQuery.filter(termQueryBuilder);
        }
        //类型
        if(StringUtils.isNotBlank(request.getType())){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("type", request.getType());
            conditionQuery.filter(termQueryBuilder);
        }
        //构建查询build
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                //索引名称
                .withIndices("log-operate")
                //索引类型
                .withTypes("log")
                //分页信息
                .withPageable(pageRequest)
                //返回字段
                .withFields(showFields)
                //组合查询build
                .withFilter(conditionQuery).build();
        //分页查询
        AggregatedPage<LogOperateResponse> responses = elasticsearchTemplate.queryForPage(searchQuery, LogOperateResponse.class);
        //数据
        resultData.setDatas(responses.getContent());
        //总记录数
        resultData.setCount(responses.getTotalElements());
        //当前页码
        resultData.setCurrentPageNum(request.getPageNum());
        logger.info("getOpResultData 查询成功！");
        return resultData;
    }
}
